package com.oa.erp.pur.ctrl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.entity.LangTips;
import com.mdp.core.entity.Result;
import com.mdp.core.query.QueryTools;
import com.mdp.core.utils.RequestUtils;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.mdp.swagger.ApiEntityParams;
import com.oa.erp.pur.entity.*;
import com.oa.erp.pur.service.OrderDetailService;
import com.oa.erp.pur.service.OrderService;
import com.oa.erp.pur.service.RequireService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月8日
 */
@RestController
@RequestMapping(value = "/*/oa/erp/pur/orderDetail")
@Api(tags = {"pur_order_detail-操作接口"})
public class OrderDetailController {

    static Logger logger = LoggerFactory.getLogger(OrderDetailController.class);


    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;


    @Autowired
    private RequireService requireService;

    @ApiOperation(value = "pur_order_detail-查询列表", notes = " ")
    @ApiEntityParams(OrderDetail.class)
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'错误码'},total:总记录数,data:[数据对象1,数据对象2,...]}")})
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public Result listOrderDetail(@ApiIgnore @RequestParam Map<String, Object> params) {
        User user = LoginUtils.getCurrentUserInfo();
        RequestUtils.transformArray(params, "assetSns");
        QueryWrapper<OrderDetail> qw = QueryTools.initQueryWrapper(OrderDetail.class, params);
        IPage page = QueryTools.initPage(params);
        List<Map<String, Object>> datas = orderDetailService.selectListMapByWhere(page, qw, params);

        return Result.ok("query-ok", "查询成功").setData(datas).setTotal(page.getTotal());
    }

    @ApiOperation(value = "将申请清单加入到某个采购单中", notes = "editOrderDetail")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/unJoinToOrder", method = RequestMethod.POST)
    public Result unJoinToOrder(@RequestBody List<RequireDetail> details) {
        details = details.stream().filter(i -> StringUtils.hasText(i.getOrderId())).collect(Collectors.toList());
        if (details.size() == 0) {
            return Result.error("data-not-exists", "请上送已加入采购单的申购明细");
        }
        String orderId = details.get(0).getOrderId();
        if (details.stream().filter(i -> !orderId.equals(i.getOrderId())).findAny().isPresent()) {
            return Result.error("data-not-right", "请上送同一个采购单的申购明细");
        }
        Order order = this.orderService.selectOneObject(new Order(orderId));
        if (order == null) {
            return Result.error("order-not-exists", "采购单已不存在");
        }
        User user = LoginUtils.getCurrentUserInfo();
        if ("1".equals(order.getBizFlowState()) && !user.getUserid().equals(order.getAssignee())) {
            return Result.error("bizFlowState-1-assignee", "已发起审批的采购单，只有当前任务执行人可以修改");
        }
        if ("2".equals(order.getBizFlowState())) {
            return Result.error("bizFlowState-2", "采购单已审批完成，无需再修改");
        }

        OrderDetail q = new OrderDetail();
        q.setPurOrderId(orderId);
        List<OrderDetail> orderDetails = this.orderDetailService.selectListByWhere(q);

        if (orderDetails == null || orderDetails.size() == 0) {
            return Result.error("orderDetails-0", "采购单已无采购明细");
        }
        Map<String, RequireDetail> requireDetailMap = new HashMap<>();
        for (RequireDetail detail : details) {
            String key = "key_" + detail.getBrandId() + "_" + detail.getBrandName() + "_" + detail.getAssetName() + "_" + detail.getSpec();
            requireDetailMap.put(key, detail);
            if (StringUtils.hasText(detail.getAssetSn())) {
                requireDetailMap.put(detail.getAssetSn(), detail);
            }
        }

        Map<String, OrderDetail> orderDetailMap = new HashMap<>();
        for (OrderDetail orderDetail : orderDetails) {
            if (orderDetail.getStockNum() == null) {
                orderDetail.setStockNum(BigDecimal.valueOf(1));
            }
            orderDetailMap.put(orderDetail.getAssetSn(), orderDetail);
            String key = "key_" + orderDetail.getBrandId() + "_" + orderDetail.getBrandName() + "_" + orderDetail.getAssetName() + "_" + orderDetail.getSpec();
            orderDetailMap.put(key, orderDetail);
        }
        Map<String, OrderDetail> updateOrderDetailsMap = new HashMap<>();
        for (RequireDetail detail : details) {
            String key = "key_" + detail.getBrandId() + "_" + detail.getBrandName() + "_" + detail.getAssetName() + "_" + detail.getSpec();
            OrderDetail orderDetail = null;
            if (StringUtils.hasText(detail.getAssetSn())) {
                orderDetail = orderDetailMap.get(detail.getAssetSn());
            }
            if (orderDetail == null) {
                orderDetail = orderDetailMap.get(key);
            }
            if (orderDetail == null) {
                continue;
            } else {
                orderDetail.setStockNum(orderDetail.getStockNum().subtract(detail.getStockNum()));
                updateOrderDetailsMap.put(orderDetail.getId(), orderDetail);
            }
        }
        this.orderDetailService.unJoinToOrder(details, new ArrayList<>(orderDetailMap.values()));

        return Result.ok();
    }

    @ApiOperation(value = "将申请清单加入到某个采购单中", notes = "editOrderDetail")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/joinToOrder", method = RequestMethod.POST)
    public Result joinToOrder(@RequestBody JoinToOrderVo joinToOrderVo) {


        User user = LoginUtils.getCurrentUserInfo();
        if (!StringUtils.hasText(joinToOrderVo.getPurOrderId())) {
            return Result.error("purOrderId-not-exists", "采购单编号不能为空purOrderId");
        }


        Order order = this.orderService.selectOneObject(new Order(joinToOrderVo.getPurOrderId()));
        if (order == null) {
            return Result.error("order-not-exists", "采购单不存在");
        }
        if ("1".equals(order.getBizFlowState()) && !user.getUserid().equals(order.getAssignee())) {
            return Result.error("bizFlowState-1", "采购单审核中，不允许修改采购单明细");
        }
        if ("2".equals(order.getBizFlowState())) {
            return Result.error("bizFlowState-2", "采购单已审核通过，不允许修改采购单明细");
        }
        List<RequireDetail> details = joinToOrderVo.getRequireDetails();
        if (details == null || details.size() == 0) {
            return Result.error("requireDetails-not-exists", "申购明细不能为空");
        }
        List<Require> requiresDb = this.requireService.selectListByDetailIds(details.stream().map(i -> i.getId()).collect(Collectors.toList()));
        List<Require> requiresNot2 = requiresDb.stream().filter(i -> !"2".equals(i.getBizFlowState())).collect(Collectors.toList());
        if (requiresNot2 != null && requiresNot2.size() > 0) {
            return Result.error("bizFlowState-not-2", "申购单" + requiresNot2.stream().map(i -> i.getReqTitle()).collect(Collectors.joining(",")) + "不是审核通过状态，不允许加入采购清单中");
        }
        OrderDetail q = new OrderDetail();
        q.setPurOrderId(order.getId());
        List<OrderDetail> orderDetailsDb = orderDetailService.selectListByWhere(q);
        Map<String, OrderDetail> orderDetailMap = new HashMap<>();
        if (orderDetailsDb == null) {
            orderDetailsDb = new ArrayList<>();
        }
        for (OrderDetail orderDetail : orderDetailsDb) {
            if (orderDetail.getStockNum() == null) {
                orderDetail.setStockNum(BigDecimal.valueOf(1));
            }
            orderDetailMap.put(orderDetail.getAssetSn(), orderDetail);
            String key = "key_" + orderDetail.getBrandId() + "_" + orderDetail.getBrandName() + "_" + orderDetail.getAssetName() + "_" + orderDetail.getSpec();
            orderDetailMap.put(key, orderDetail);
        }
        Map<String, RequireDetail> requireDetailMap = new HashMap<>();
        //先进行一次同种资产数量合并
        for (RequireDetail detail : details) {

            if (detail.getStockNum() == null) {
                detail.setStockNum(BigDecimal.valueOf(1));
            }
            String key = "key_" + detail.getBrandId() + "_" + detail.getBrandName() + "_" + detail.getAssetName() + "_" + detail.getSpec();
            if (StringUtils.hasText(detail.getAssetSn())) {
                if (requireDetailMap.containsKey(detail.getAssetSn())) {
                    RequireDetail requireDetail = requireDetailMap.get(detail.getAssetSn());
                    requireDetail.setStockNum(requireDetail.getStockNum().add(detail.getStockNum()));
                } else {
                    requireDetailMap.put(key, detail);
                    requireDetailMap.put(detail.getAssetSn(), detail);
                }
            } else if (requireDetailMap.containsKey(key)) {
                RequireDetail requireDetail = requireDetailMap.get(key);
                requireDetail.setStockNum(requireDetail.getStockNum().add(detail.getStockNum()));
                if (StringUtils.hasText(requireDetail.getAssetSn())) {
                    requireDetailMap.put(requireDetail.getAssetSn(), requireDetail);
                }
            } else {
                requireDetailMap.put(key, detail);
            }
        }
        Map<String, RequireDetail> requireDetailMap2 = new HashMap<>();
        requireDetailMap.forEach((key, detail) -> {
            if (key.startsWith("key_")) {
                requireDetailMap2.put(key, detail);
            }
        });
        List<OrderDetail> orderDetailsInsert = new ArrayList<>();

        List<OrderDetail> orderDetailsUpdate = new ArrayList<>();
        for (RequireDetail detail : requireDetailMap2.values()) {
            if (StringUtils.hasText(detail.getAssetSn())) {
                if (orderDetailMap.containsKey(detail.getAssetSn())) {
                    OrderDetail updateOrderDetail = orderDetailMap.get(detail.getAssetSn());
                    updateOrderDetail.setStockNum(detail.getStockNum().add(updateOrderDetail.getStockNum()));
                    orderDetailsUpdate.add(updateOrderDetail);
                    detail.setOrderDetailId(updateOrderDetail.getId());
                } else {
                    OrderDetail insertOrderDetail = new OrderDetail();
                    BeanUtils.copyProperties(detail, insertOrderDetail);
                    insertOrderDetail.setId(this.orderDetailService.createKey("id"));
                    insertOrderDetail.setPurOrderId(joinToOrderVo.getPurOrderId());
                    detail.setOrderDetailId(insertOrderDetail.getId());
                    orderDetailsInsert.add(insertOrderDetail);
                }
            } else {
                String key = "key_" + detail.getBrandId() + "_" + detail.getBrandName() + "_" + detail.getAssetName() + "_" + detail.getSpec();
                if (orderDetailMap.containsKey(key)) {
                    OrderDetail updateOrderDetail = orderDetailMap.get(key);
                    updateOrderDetail.setStockNum(detail.getStockNum().add(updateOrderDetail.getStockNum()));
                    orderDetailsUpdate.add(updateOrderDetail);
                    detail.setOrderDetailId(updateOrderDetail.getId());
                } else {
                    OrderDetail insertOrderDetail = new OrderDetail();
                    BeanUtils.copyProperties(detail, insertOrderDetail);
                    insertOrderDetail.setId(this.orderDetailService.createKey("id"));
                    insertOrderDetail.setPurOrderId(joinToOrderVo.getPurOrderId());
                    detail.setOrderDetailId(insertOrderDetail.getId());
                    orderDetailsInsert.add(insertOrderDetail);
                }
            }


            detail.setOrderId(joinToOrderVo.getPurOrderId());
        }

        for (RequireDetail detail : details) {
            String key = "key_" + detail.getBrandId() + "_" + detail.getBrandName() + "_" + detail.getAssetName() + "_" + detail.getSpec();
            if (StringUtils.hasText(detail.getAssetSn())) {
                if (!StringUtils.hasText(detail.getOrderDetailId())) {
                    RequireDetail detail1 = requireDetailMap.get(detail.getAssetSn());
                    detail.setOrderDetailId(detail1.getOrderDetailId());
                    detail.setOrderId(detail1.getOrderId());
                }
            } else {
                if (!StringUtils.hasText(detail.getOrderDetailId())) {
                    RequireDetail detail1 = requireDetailMap.get(key);
                    detail.setOrderDetailId(detail1.getOrderDetailId());
                    detail.setOrderId(detail1.getOrderId());
                }
            }
        }

        orderDetailService.joinToOrder(orderDetailsInsert, orderDetailsUpdate, details);

        return Result.ok();
    }

    @ApiOperation(value = "pur_order_detail-新增", notes = " ")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Result addOrderDetail(@RequestBody OrderDetail orderDetail) {
        orderDetailService.save(orderDetail);
        return Result.ok("add-ok", "添加成功！");
    }

    @ApiOperation(value = "pur_order_detail-删除", notes = " ")
    @ApiResponses({@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}}")})
    @RequestMapping(value = "/del", method = RequestMethod.POST)
    public Result delOrderDetail(@RequestBody OrderDetail orderDetail) {
        orderDetailService.removeById(orderDetail);
        return Result.ok("del-ok", "删除成功！");
    }

    @ApiOperation(value = "pur_order_detail-修改", notes = " ")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public Result editOrderDetail(@RequestBody OrderDetail orderDetail) {
        orderDetailService.updateById(orderDetail);
        return Result.ok("edit-ok", "修改成功！");
    }

    @ApiOperation(value = "pur_order_detail-批量修改某些字段", notes = "")
    @ApiEntityParams(value = OrderDetail.class, props = {}, remark = "pur_order_detail", paramType = "body")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/editSomeFields", method = RequestMethod.POST)
    public Result editSomeFields(@ApiIgnore @RequestBody Map<String, Object> params) {
        User user = LoginUtils.getCurrentUserInfo();
        orderDetailService.editSomeFields(params);
        return Result.ok("edit-ok", "更新成功");
    }

    @ApiOperation(value = "pur_order_detail-批量删除", notes = " ")
    @ApiResponses({@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}")})
    @RequestMapping(value = "/batchDel", method = RequestMethod.POST)
    public Result batchDelOrderDetail(@RequestBody List<OrderDetail> orderDetails) {
        User user = LoginUtils.getCurrentUserInfo();
        if (orderDetails.size() <= 0) {
            return Result.error("batchDel-data-err-0", "请上送待删除数据列表");
        }
        List<OrderDetail> datasDb = orderDetailService.listByIds(orderDetails.stream().map(i -> i.getId()).collect(Collectors.toList()));

        List<OrderDetail> can = new ArrayList<>();
        List<OrderDetail> no = new ArrayList<>();
        for (OrderDetail data : datasDb) {
            if (true) {
                can.add(data);
            } else {
                no.add(data);
            }
        }
        List<String> msgs = new ArrayList<>();
        if (can.size() > 0) {
            orderDetailService.removeByIds(can);
            msgs.add(LangTips.transMsg("del-ok-num", "成功删除%s条数据.", can.size()));
        }

        if (no.size() > 0) {
            msgs.add(LangTips.transMsg("not-allow-del-num", "以下%s条数据不能删除:【%s】", no.size(), no.stream().map(i -> i.getId()).collect(Collectors.joining(","))));
        }
        if (can.size() > 0) {
            return Result.ok(msgs.stream().collect(Collectors.joining()));
        } else {
            return Result.error(msgs.stream().collect(Collectors.joining()));
        }
    }

    @ApiOperation(value = "pur_order_detail-根据主键查询一条数据", notes = " ")
    @ApiResponses({@ApiResponse(code = 200, response = OrderDetail.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")})
    @RequestMapping(value = "/queryById", method = RequestMethod.GET)
    public Result queryById(OrderDetail orderDetail) {
        OrderDetail data = (OrderDetail) orderDetailService.getById(orderDetail);
        return Result.ok().setData(data);
    }

}
